<?php

declare(strict_types=1);
/**
 * This file is part of Hyperf.
 *
 * @link     https://www.hyperf.io
 * @document https://doc.hyperf.io
 * @contact  group@hyperf.io
 * @license  https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
 */

namespace App\Server\Model;

use Hyperf\DbConnection\Model\Model as BaseModel;
use Hyperf\ModelCache\Cacheable;
use Hyperf\ModelCache\CacheableInterface;
use App\Server\Cache\Cache;


abstract class Model extends BaseModel implements CacheableInterface
{
    use Cacheable;
    public $keys = [];

    public function getModuleParams()
    {
        switch (true) {
            case ($this instanceof Admin):
                break;
            case ($this instanceof AdminGroup):
                break;
            default:
                break;
        }
    }

    final public function dataAdd($data){
        return self::query()->insert($data);
    }

    final public function dataFirstOrCreate($condition,$data){
        return self::query()->firstOrCreate($condition,$data);
    }

    final public function dataUpdateOrInsert($condition,$data){
        return self::query()->updateOrInsert($condition,$data);
    }

    final public function dataDelete($where){
        return self::query()->where($where)->delete();
    }

    final public function dataIncrement($where,$field,$num){
        return self::query()->where($where)->increment($field,$num);
    }

    final public function dataDecrement($where,$field,$num){
        return self::query()->where($where)->decrement($field,$num);
    }

    final public function dataUpdate($where,$data)
    {
        return self::query()->where($where)->update($data);
    }

    final public function getValue($where,$field){
        return self::query()->where($where)->value($field);
    }

    final public function getPluck($where,$field){
        return self::query()->where($where)->pluck($field);
    }

    final public function dataCount($where = []){
        return self::query()->where($where)->count();
    }

    final public function getInfo($where,$field){
        $res = self::query()->where($where)->select($field)->first();
        return !empty($res) ? $res->toArray() : [];
    }

    final public function getList($where,$field,$order=''){
        $whereIn = [];
        if (isset($where['whereIn'])){
            $whereIn = $where['whereIn'];
            unset($where['whereIn']);
        }
        $res = self::query()->where($where)->select($field)
                        ->when($order,function($query,$order){
                            $query->orderByRaw($order);
                        })
                        ->when($whereIn,function($query,$whereIn){
                            foreach ($whereIn as $v) {
                                $query->whereIn($v[0], $v[1]);
                            }
                        })->get();
        return !empty($res) ? $res->toArray() : [];
    }

    final public function getListPage($where,$field=['*'],$order=null,$group=null,$page_size=20){
        $unity_search =[];
        if (isset($where['unity_search'])){
            $unity_search = $where['unity_search'];
            unset($where['unity_search']);
        }
        $whereIn = [];
        if (isset($where['whereIn'])){
            $whereIn = $where['whereIn'];
            unset($where['whereIn']);
        }
        $res = self::query()->where($where)
                        ->when($unity_search,function($query,$unity_search){
                            return $query->where(function($query) use ($unity_search){
                                $flag = false;
                                foreach ($unity_search as $v){
                                    if (!$flag){
                                        $query->where([[$v[0], 'like', "%{$v[1]}%"]]);
                                        $flag = true;
                                    }else{
                                        $query->orWhere([[$v[0], 'like', "%{$v[1]}%"]]);
                                    }
                                }
                            });
                        })
                        ->when($whereIn,function($query,$whereIn){
                            foreach ($whereIn as $v) {
                                $query->whereIn($v[0], $v[1]);
                            }
                        })
                        ->when($order,function($query,$order){
                            $query->orderByRaw($order);
                        })
                        ->when($group,function($query,$group){
                            $query->groupBy($group);
                        })
                        ->paginate($page_size,$field);
        return !empty($res) ? $res->toArray() : [];
    }

    public function getCacheInfo($where,$cacheKey,$action='find',$field='*',$ttl=86400){
        $this->getModuleParams();
        $cache = new Cache();
        if (!$cache->has($cacheKey)||$action == 'update'){
            $res = $this->getInfo($where,$field);
            $cache->set($cacheKey, $res, $ttl);
        }else{
            $res = $cache->get($cacheKey);
        }
        return $res;
    }

    final public function getCacheList($where,$cacheKey,$action='update',$field='*',$ttl=86400,$order = 'orders asc'){
        $cache = new Cache();
        if (!$cache->has($cacheKey)||$action == 'update'){
            $res = $this->getList($where,$field,$order);
            $cache->set($cacheKey, $res, $ttl);
        }else{
            $res = $cache->get($cacheKey);
        }
        return $res;
    }

    public function clearCacheData(){
        $keys = $this->keys;
        $resa = new \App\Server\Cache\Cache();
        $clearRes = $resa->deleteMultiple($keys);
        return $clearRes;
    }
}
